home *** CD-ROM | disk | FTP | other *** search
/ X User Tools / X User Tools (O'Reilly and Associates)(1994).ISO / sources / libxpm / libxpm34.gz / libxpm34 / xpm-3.4 / lib / scan.c < prev    next >
C/C++ Source or Header  |  1994-03-14  |  21KB  |  795 lines

  1. /* Copyright 1989-94 GROUPE BULL -- See license conditions in file COPYRIGHT */
  2. /*****************************************************************************\
  3. * scan.c:                                                                     *
  4. *                                                                             *
  5. *  XPM library                                                                *
  6. *  Scanning utility for XPM file format                                        *
  7. *                                                                             *
  8. *  Developed by Arnaud Le Hors                                                *
  9. \*****************************************************************************/
  10.  
  11. #include "xpmP.h"
  12.  
  13. #define MAXPRINTABLE 92            /* number of printable ascii chars
  14.                      * minus \ and " for string compat
  15.                      * and ? to avoid ANSI trigraphs. */
  16.  
  17. static char *printable =
  18. " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\
  19. ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
  20.  
  21. /*
  22.  * printable begin with a space, so in most case, due to my algorithm, when
  23.  * the number of different colors is less than MAXPRINTABLE, it will give a
  24.  * char follow by "nothing" (a space) in the readable xpm file
  25.  */
  26.  
  27.  
  28. typedef struct {
  29.     Pixel *pixels;
  30.     unsigned int *pixelindex;
  31.     unsigned int size;
  32.     unsigned int ncolors;
  33.     unsigned int mask_pixel;        /* whether there is or not */
  34. }      PixelsMap;
  35.  
  36. LFUNC(storePixel, int, (Pixel pixel, PixelsMap *pmap,
  37.             unsigned int *index_return));
  38.  
  39. LFUNC(storeMaskPixel, int, (Pixel pixel, PixelsMap *pmap,
  40.                 unsigned int *index_return));
  41.  
  42. LFUNC(GetImagePixels, int, (XImage *image, unsigned int width,
  43.                 unsigned int height, PixelsMap *pmap));
  44.  
  45. LFUNC(GetImagePixels32, int, (XImage *image, unsigned int width,
  46.                   unsigned int height, PixelsMap *pmap));
  47.  
  48. LFUNC(GetImagePixels16, int, (XImage *image, unsigned int width,
  49.                   unsigned int height, PixelsMap *pmap));
  50.  
  51. LFUNC(GetImagePixels8, int, (XImage *image, unsigned int width,
  52.                  unsigned int height, PixelsMap *pmap));
  53.  
  54. LFUNC(GetImagePixels1, int, (XImage *image, unsigned int width,
  55.                  unsigned int height, PixelsMap *pmap,
  56.                  int (*storeFunc) ()));
  57.  
  58. LFUNC(ScanTransparentColor, int, (XpmColor *color, unsigned int cpp,
  59.                   XpmAttributes *attributes));
  60.  
  61. LFUNC(ScanOtherColors, int, (Display *display, XpmColor *colors, int ncolors,
  62.                  Pixel *pixels, unsigned int mask,
  63.                  unsigned int cpp, XpmAttributes *attributes));
  64.  
  65. /*
  66.  * This function stores the given pixel in the given arrays which are grown
  67.  * if not large enough.
  68.  */
  69. static int
  70. storePixel(pixel, pmap, index_return)
  71.     Pixel pixel;
  72.     PixelsMap *pmap;
  73.     unsigned int *index_return;
  74. {
  75.     unsigned int i;
  76.     Pixel *p;
  77.     unsigned int ncolors;
  78.  
  79.     if (*index_return) {        /* this is a transparent pixel! */
  80.     *index_return = 0;
  81.     return 0;
  82.     }
  83.     ncolors = pmap->ncolors;
  84.     p = pmap->pixels + pmap->mask_pixel;
  85.     for (i = pmap->mask_pixel; i < ncolors; i++, p++)
  86.     if (*p == pixel)
  87.         break;
  88.     if (i == ncolors) {
  89.     if (ncolors >= pmap->size) {
  90.         pmap->size *= 2;
  91.         p = (Pixel *) XpmRealloc(pmap->pixels, sizeof(Pixel) * pmap->size);
  92.         if (!p)
  93.         return (1);
  94.         pmap->pixels = p;
  95.  
  96.     }
  97.     (pmap->pixels)[ncolors] = pixel;
  98.     pmap->ncolors++;
  99.     }
  100.     *index_return = i;
  101.     return 0;
  102. }
  103.  
  104. static int
  105. storeMaskPixel(pixel, pmap, index_return)
  106.     Pixel pixel;
  107.     PixelsMap *pmap;
  108.     unsigned int *index_return;
  109. {
  110.     if (!pixel) {
  111.     if (!pmap->ncolors) {
  112.         pmap->ncolors = 1;
  113.         (pmap->pixels)[0] = 0;
  114.         pmap->mask_pixel = 1;
  115.     }
  116.     *index_return = 1;
  117.     } else
  118.     *index_return = 0;
  119.     return 0;
  120. }
  121.  
  122. /* function call in case of error, frees only locally allocated variables */
  123. #undef RETURN
  124. #define RETURN(status) \
  125. { \
  126.     if (pmap.pixelindex) XpmFree(pmap.pixelindex); \
  127.     if (pmap.pixels) XpmFree(pmap.pixels); \
  128.     if (colorTable) xpmFreeColorTable(colorTable, pmap.ncolors); \
  129.     return(status); \
  130. }
  131.  
  132. /*
  133.  * This function scans the given image and stores the found informations in
  134.  * the given XpmImage structure.
  135.  */
  136. int
  137. XpmCreateXpmImageFromImage(display, image, shapeimage,
  138.                xpmimage, attributes)
  139.     Display *display;
  140.     XImage *image;
  141.     XImage *shapeimage;
  142.     XpmImage *xpmimage;
  143.     XpmAttributes *attributes;
  144. {
  145.     /* variables stored in the XpmAttributes structure */
  146.     unsigned int cpp;
  147.  
  148.     /* variables to return */
  149.     PixelsMap pmap;
  150.     XpmColor *colorTable = NULL;
  151.     int ErrorStatus;
  152.  
  153.     /* calculation variables */
  154.     unsigned int width = 0;
  155.     unsigned int height = 0;
  156.     unsigned int cppm;            /* minimum chars per pixel */
  157.     unsigned int c;
  158.     unsigned int offset;
  159.  
  160.     /* initialize pmap */
  161.     pmap.pixels = NULL;
  162.     pmap.pixelindex = NULL;
  163.     pmap.size = 256;            /* should be enough most of the time */
  164.     pmap.ncolors = 0;
  165.     pmap.mask_pixel = 0;
  166.  
  167.     /*
  168.      * get geometry
  169.      */
  170.     if (image) {
  171.     width = image->width;
  172.     height = image->height;
  173.     } else if (shapeimage) {
  174.     width = shapeimage->width;
  175.     height = shapeimage->height;
  176.     }
  177.  
  178.     /*
  179.      * retrieve information from the XpmAttributes
  180.      */
  181.     if (attributes && (attributes->valuemask & XpmCharsPerPixel
  182. /* 3.2 backward compatibility code */
  183.                        || attributes->valuemask & XpmInfos))
  184. /* end 3.2 bc */
  185.     cpp = attributes->cpp;
  186.     else
  187.     cpp = 0;
  188.  
  189.     pmap.pixelindex =
  190.     (unsigned int *) XpmCalloc(width * height, sizeof(unsigned int));
  191.     if (!pmap.pixelindex)
  192.     RETURN(XpmNoMemory);
  193.  
  194.     pmap.pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * pmap.size);
  195.     if (!pmap.pixels)
  196.     RETURN(XpmNoMemory);
  197.  
  198.     /*
  199.      * scan shape mask if any
  200.      */
  201.     if (shapeimage) {
  202.     ErrorStatus = GetImagePixels1(shapeimage, width, height, &pmap,
  203.                       storeMaskPixel);
  204.     if (ErrorStatus != XpmSuccess)
  205.         RETURN(ErrorStatus);
  206.     }
  207.  
  208.     /*
  209.      * scan the image data
  210.      * 
  211.      * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use optimized
  212.      * functions, otherwise use slower but sure general one.
  213.      * 
  214.      */
  215.  
  216.     if (image) {
  217.     if (image->depth == 1)
  218.         ErrorStatus = GetImagePixels1(image, width, height, &pmap,
  219.                       storePixel);
  220.     else if (image->bits_per_pixel == 8)
  221.         ErrorStatus = GetImagePixels8(image, width, height, &pmap);
  222.     else if (image->bits_per_pixel == 16)
  223.         ErrorStatus = GetImagePixels16(image, width, height, &pmap);
  224.     else if (image->bits_per_pixel == 32)
  225.         ErrorStatus = GetImagePixels32(image, width, height, &pmap);
  226.     else
  227.         ErrorStatus = GetImagePixels(image, width, height, &pmap);
  228.  
  229.     if (ErrorStatus != XpmSuccess)
  230.         RETURN(ErrorStatus);
  231.     }
  232.  
  233.     /*
  234.      * get rgb values and a string of char, and possibly a name for each
  235.      * color
  236.      */
  237.  
  238.     colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor));
  239.     if (!colorTable)
  240.     RETURN(XpmNoMemory);
  241.  
  242.     /* compute the minimal cpp */
  243.     for (cppm = 1, c = MAXPRINTABLE; pmap.ncolors > c; cppm++)
  244.     c *= MAXPRINTABLE;
  245.     if (cpp < cppm)
  246.     cpp = cppm;
  247.  
  248.     if (pmap.mask_pixel) {
  249.     ErrorStatus = ScanTransparentColor(colorTable, cpp, attributes);
  250.     if (ErrorStatus != XpmSuccess)
  251.         RETURN(ErrorStatus);
  252.     offset = 1;
  253.     } else
  254.     offset = 0;
  255.  
  256.     ErrorStatus = ScanOtherColors(display, colorTable + offset,
  257.                   pmap.ncolors - offset, pmap.pixels + offset,
  258.                   pmap.mask_pixel, cpp, attributes);
  259.     if (ErrorStatus != XpmSuccess)
  260.     RETURN(ErrorStatus);
  261.  
  262.     /*
  263.      * store found informations in the XpmImage structure
  264.      */
  265.     xpmimage->width = width;
  266.     xpmimage->height = height;
  267.     xpmimage->cpp = cpp;
  268.     xpmimage->ncolors = pmap.ncolors;
  269.     xpmimage->colorTable = colorTable;
  270.     xpmimage->data = pmap.pixelindex;
  271.  
  272.     XpmFree(pmap.pixels);
  273.     return (XpmSuccess);
  274. }
  275.  
  276. static int
  277. ScanTransparentColor(color, cpp, attributes)
  278.     XpmColor *color;
  279.     unsigned int cpp;
  280.     XpmAttributes *attributes;
  281. {
  282.     char *s;
  283.     unsigned int a, b, c;
  284.  
  285.     /* first get a character string */
  286.     a = 0;
  287.     if (!(s = color->string = (char *) XpmMalloc(cpp + 1)))
  288.     return (XpmNoMemory);
  289.     *s++ = printable[c = a % MAXPRINTABLE];
  290.     for (b = 1; b < cpp; b++, s++)
  291.     *s = printable[c = ((a - c) / MAXPRINTABLE) % MAXPRINTABLE];
  292.     *s = '\0';
  293.  
  294.     /* then retreive related info from the attributes if any */
  295.     if (attributes && attributes->mask_pixel != XpmUndefPixel && (
  296. /* 3.2 backward compatibility code */
  297.     attributes->valuemask & XpmInfos ||
  298. /* end 3.2 bc */
  299.     attributes->valuemask & XpmColorTable)) {
  300.  
  301.         unsigned int key;
  302.         char **defaults = (char **) color;
  303.         char **mask_defaults;
  304.  
  305. /* 3.2 backward compatibility code */
  306.         if (attributes->valuemask & XpmInfos)
  307.         mask_defaults = (char **)
  308.             ((XpmColor **)
  309.              attributes->colorTable)[attributes->mask_pixel];
  310.         else
  311. /* end 3.2 bc */
  312.         mask_defaults = (char **) (
  313.             attributes->colorTable + attributes->mask_pixel);
  314.         for (key = 1; key <= NKEYS; key++) {
  315.         if (s = mask_defaults[key]) {
  316.             defaults[key] = (char *) strdup(s);
  317.             if (!defaults[key])
  318.             return (XpmNoMemory);
  319.         }
  320.         }
  321.     } else {
  322.     color->c_color = (char *) strdup(TRANSPARENT_COLOR);
  323.     if (!color->c_color)
  324.         return (XpmNoMemory);
  325.     }
  326.     return (XpmSuccess);
  327. }
  328.  
  329. static int
  330. ScanOtherColors(display, colors, ncolors, pixels, mask, cpp, attributes)
  331.     Display *display;
  332.     XpmColor *colors;
  333.     int ncolors;
  334.     Pixel *pixels;
  335.     unsigned int cpp;
  336.     unsigned int mask;
  337.     XpmAttributes *attributes;
  338. {
  339.     /* variables stored in the XpmAttributes structure */
  340.     Colormap colormap;
  341.     char *rgb_fname;
  342.  
  343.     xpmRgbName rgbn[MAX_RGBNAMES];
  344.     int rgbn_max = 0;
  345.     unsigned int i, j, c, found, i2;
  346.     XpmColor *color;
  347.     XColor *xcolors = NULL, *xcolor;
  348.     char *colorname, *s;
  349.     XpmColor *colorTable, **oldColorTable = NULL;
  350.     unsigned int ancolors = 0;
  351.     Pixel *apixels;
  352.     unsigned int mask_pixel;
  353.  
  354.     /* retrieve information from the XpmAttributes */
  355.     if (attributes && (attributes->valuemask & XpmColormap))
  356.     colormap = attributes->colormap;
  357.     else
  358.     colormap = DefaultColormap(display, DefaultScreen(display));
  359.     if (attributes && (attributes->valuemask & XpmRgbFilename))
  360.     rgb_fname = attributes->rgb_fname;
  361.     else
  362.     rgb_fname = NULL;
  363.  
  364.     /* first get character strings and rgb values */
  365.     xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors);
  366.     if (!xcolors)
  367.     return (XpmNoMemory);
  368.  
  369.     for (i = 0, i2 = (mask ? i + 1 : i), color = colors, xcolor = xcolors;
  370.      i < ncolors; i++, i2++, color++, xcolor++, pixels++) {
  371.  
  372.     if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) {
  373.         XpmFree(xcolors);
  374.         return (XpmNoMemory);
  375.     }
  376.     *s++ = printable[c = i2  % MAXPRINTABLE];
  377.     for (j = 1; j < cpp; j++, s++)
  378.         *s = printable[c = ((i2 - c) / MAXPRINTABLE) % MAXPRINTABLE];
  379.     *s = '\0';
  380.  
  381.     xcolor->pixel = *pixels;
  382.     }
  383.     XQueryColors(display, colormap, xcolors, ncolors);
  384.  
  385.     /* read the rgb file if any was specified */
  386.     if (rgb_fname)
  387.     rgbn_max = xpmReadRgbNames(attributes->rgb_fname, rgbn);
  388.  
  389.     if (attributes && attributes->valuemask & XpmColorTable) {
  390.     colorTable = attributes->colorTable;
  391.     ancolors = attributes->ncolors;
  392.     apixels = attributes->pixels;
  393.     mask_pixel = attributes->mask_pixel;
  394.     }
  395. /* 3.2 backward compatibility code */
  396.     else if (attributes && attributes->valuemask & XpmInfos) {
  397.     oldColorTable = (XpmColor **) attributes->colorTable;
  398.     ancolors = attributes->ncolors;
  399.     apixels = attributes->pixels;
  400.     mask_pixel = attributes->mask_pixel;
  401.     }
  402. /* end 3.2 bc */
  403.  
  404.     for (i = 0, color = colors, xcolor = xcolors; i < ncolors;
  405.                           i++, color++, xcolor++) {
  406.  
  407.     /* look for related info from the attributes if any */
  408.     found = 0;
  409.     if (ancolors) {
  410.         unsigned int offset = 0;
  411.         for (j = 0; j < ancolors; j++) {
  412.         if (j == mask_pixel) {
  413.             offset = 1;
  414.             continue;
  415.         }
  416.         if (apixels[j - offset] == xcolor->pixel)
  417.             break;
  418.         }
  419.         if (j != ancolors) {
  420.         unsigned int key;
  421.         char **defaults = (char **) color;
  422.         char **adefaults;
  423. /* 3.2 backward compatibility code */
  424.         if (oldColorTable)
  425.             adefaults = (char **) oldColorTable[j];
  426.         else
  427. /* end 3.2 bc */
  428.             adefaults = (char **) (colorTable + j);
  429.  
  430.         found = 1;
  431.         for (key = 1; key <= NKEYS; key++) {
  432.             if (s = adefaults[key])
  433.             defaults[key] = (char *) strdup(s);
  434.         }
  435.         }
  436.     }
  437.     if (!found) {
  438.         /* if nothing found look for a color name */
  439.         colorname = NULL;
  440.         if (rgbn_max)
  441.         colorname = xpmGetRgbName(rgbn, rgbn_max, xcolor->red,
  442.                       xcolor->green, xcolor->blue);
  443.         if (colorname)
  444.         color->c_color = (char *) strdup(colorname);
  445.         else {
  446.         /* at last store the rgb value */
  447.         char buf[BUFSIZ];
  448.  
  449.         sprintf(buf, "#%04X%04X%04X",
  450.             xcolor->red, xcolor->green, xcolor->blue);
  451.         color->c_color = (char *) strdup(buf);
  452.         }
  453.         if (!color->c_color) {
  454.         XpmFree(xcolors);
  455.         xpmFreeRgbNames(rgbn, rgbn_max);
  456.         return (XpmNoMemory);
  457.         }
  458.     }
  459.     }
  460.  
  461.     XpmFree(xcolors);
  462.     xpmFreeRgbNames(rgbn, rgbn_max);
  463.     return (XpmSuccess);
  464. }
  465.  
  466.  
  467. /*
  468.  * The functions below are written from X11R5 MIT's code (XImUtil.c)
  469.  *
  470.  * The idea is to have faster functions than the standard XGetPixel function
  471.  * to scan the image data. Indeed we can speed up things by suppressing tests
  472.  * performed for each pixel. We do exactly the same tests but at the image
  473.  * level. Assuming that we use only ZPixmap images.
  474.  */
  475.  
  476. static unsigned long Const low_bits_table[] = {
  477.     0x00000000, 0x00000001, 0x00000003, 0x00000007,
  478.     0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
  479.     0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
  480.     0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
  481.     0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
  482.     0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
  483.     0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
  484.     0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
  485.     0xffffffff
  486. };
  487.  
  488. /*
  489.  * Default method to scan pixels of a Z image data structure.
  490.  * The algorithm used is:
  491.  *
  492.  *    copy the source bitmap_unit or Zpixel into temp
  493.  *    normalize temp if needed
  494.  *    extract the pixel bits into return value
  495.  *
  496.  */
  497.  
  498. static int
  499. GetImagePixels(image, width, height, pmap)
  500.     XImage *image;
  501.     unsigned int width;
  502.     unsigned int height;
  503.     PixelsMap *pmap;
  504. {
  505.     char *src;
  506.     char *dst;
  507.     unsigned int *iptr;
  508.     char *data;
  509.     int x, y, i;
  510.     int bits, depth, ibu, ibpp;
  511.     unsigned long lbt;
  512.     Pixel pixel, px;
  513.  
  514.     data = image->data;
  515.     iptr = pmap->pixelindex;
  516.     depth = image->depth;
  517.     lbt = low_bits_table[depth];
  518.     ibpp = image->bits_per_pixel;
  519.     if (image->depth == 1) {
  520.     ibu = image->bitmap_unit;
  521.     for (y = 0; y < height; y++)
  522.         for (x = 0; x < width; x++, iptr++) {
  523.         src = &data[XYINDEX(x, y, image)];
  524.         dst = (char *) &pixel;
  525.         pixel = 0;
  526.         for (i = ibu >> 3; --i >= 0;)
  527.             *dst++ = *src++;
  528.         XYNORMALIZE(&pixel, image);
  529.         bits = x % ibu;
  530.         pixel = ((((char *) &pixel)[bits >> 3]) >> (bits & 7)) & 1;
  531.         if (ibpp != depth)
  532.             pixel &= lbt;
  533.         if (storePixel(pixel, pmap, iptr))
  534.             return (XpmNoMemory);
  535.         }
  536.     } else {
  537.     for (y = 0; y < height; y++)
  538.         for (x = 0; x < width; x++, iptr++) {
  539.         src = &data[ZINDEX(x, y, image)];
  540.         dst = (char *) &px;
  541.         px = 0;
  542.         for (i = (ibpp + 7) >> 3; --i >= 0;)
  543.             *dst++ = *src++;
  544.         ZNORMALIZE(&px, image);
  545.         pixel = 0;
  546.         for (i = sizeof(unsigned long); --i >= 0;)
  547.             pixel = (pixel << 8) | ((unsigned char *) &px)[i];
  548.         if (ibpp == 4) {
  549.             if (x & 1)
  550.             pixel >>= 4;
  551.             else
  552.             pixel &= 0xf;
  553.         }
  554.         if (ibpp != depth)
  555.             pixel &= lbt;
  556.         if (storePixel(pixel, pmap, iptr))
  557.             return (XpmNoMemory);
  558.         }
  559.     }
  560.     return (XpmSuccess);
  561. }
  562.  
  563. /*
  564.  * scan pixels of a 32-bits Z image data structure
  565.  */
  566.  
  567. #ifndef WORD64
  568. static unsigned long byteorderpixel = MSBFirst << 24;
  569.  
  570. #endif
  571.  
  572. static int
  573. GetImagePixels32(image, width, height, pmap)
  574.     XImage *image;
  575.     unsigned int width;
  576.     unsigned int height;
  577.     PixelsMap *pmap;
  578. {
  579.     unsigned char *addr;
  580.     unsigned char *data;
  581.     unsigned int *iptr;
  582.     int x, y;
  583.     unsigned long lbt;
  584.     Pixel pixel;
  585.     int depth;
  586.  
  587.     data = (unsigned char *) image->data;
  588.     iptr = pmap->pixelindex;
  589.     depth = image->depth;
  590.     lbt = low_bits_table[depth];
  591. #ifndef WORD64
  592.     if (*((char *) &byteorderpixel) == image->byte_order) {
  593.     for (y = 0; y < height; y++)
  594.         for (x = 0; x < width; x++, iptr++) {
  595.         addr = &data[ZINDEX32(x, y, image)];
  596.         pixel = *((unsigned long *) addr);
  597.         if (depth != 32)
  598.             pixel &= lbt;
  599.         if (storePixel(pixel, pmap, iptr))
  600.             return (XpmNoMemory);
  601.         }
  602.     } else
  603. #endif
  604.     if (image->byte_order == MSBFirst)
  605.     for (y = 0; y < height; y++)
  606.         for (x = 0; x < width; x++, iptr++) {
  607.         addr = &data[ZINDEX32(x, y, image)];
  608.         pixel = ((unsigned long) addr[0] << 24 |
  609.              (unsigned long) addr[1] << 16 |
  610.              (unsigned long) addr[2] << 8 |
  611.              addr[4]);
  612.         if (depth != 32)
  613.             pixel &= lbt;
  614.         if (storePixel(pixel, pmap, iptr))
  615.             return (XpmNoMemory);
  616.         }
  617.     else
  618.     for (y = 0; y < height; y++)
  619.         for (x = 0; x < width; x++, iptr++) {
  620.         addr = &data[ZINDEX32(x, y, image)];
  621.         pixel = (addr[0] |
  622.              (unsigned long) addr[1] << 8 |
  623.              (unsigned long) addr[2] << 16 |
  624.              (unsigned long) addr[3] << 24);
  625.         if (depth != 32)
  626.             pixel &= lbt;
  627.         if (storePixel(pixel, pmap, iptr))
  628.             return (XpmNoMemory);
  629.         }
  630.     return (XpmSuccess);
  631. }
  632.  
  633. /*
  634.  * scan pixels of a 16-bits Z image data structure
  635.  */
  636.  
  637. static int
  638. GetImagePixels16(image, width, height, pmap)
  639.     XImage *image;
  640.     unsigned int width;
  641.     unsigned int height;
  642.     PixelsMap *pmap;
  643. {
  644.     unsigned char *addr;
  645.     unsigned char *data;
  646.     unsigned int *iptr;
  647.     int x, y;
  648.     unsigned long lbt;
  649.     Pixel pixel;
  650.     int depth;
  651.  
  652.     data = (unsigned char *) image->data;
  653.     iptr = pmap->pixelindex;
  654.     depth = image->depth;
  655.     lbt = low_bits_table[depth];
  656.     if (image->byte_order == MSBFirst)
  657.     for (y = 0; y < height; y++)
  658.         for (x = 0; x < width; x++, iptr++) {
  659.         addr = &data[ZINDEX16(x, y, image)];
  660.         pixel = addr[0] << 8 | addr[1];
  661.         if (depth != 16)
  662.             pixel &= lbt;
  663.         if (storePixel(pixel, pmap, iptr))
  664.             return (XpmNoMemory);
  665.         }
  666.     else
  667.     for (y = 0; y < height; y++)
  668.         for (x = 0; x < width; x++, iptr++) {
  669.         addr = &data[ZINDEX16(x, y, image)];
  670.         pixel = addr[0] | addr[1] << 8;
  671.         if (depth != 16)
  672.             pixel &= lbt;
  673.         if (storePixel(pixel, pmap, iptr))
  674.             return (XpmNoMemory);
  675.         }
  676.     return (XpmSuccess);
  677. }
  678.  
  679. /*
  680.  * scan pixels of a 8-bits Z image data structure
  681.  */
  682.  
  683. static int
  684. GetImagePixels8(image, width, height, pmap)
  685.     XImage *image;
  686.     unsigned int width;
  687.     unsigned int height;
  688.     PixelsMap *pmap;
  689. {
  690.     unsigned int *iptr;
  691.     unsigned char *data;
  692.     int x, y;
  693.     unsigned long lbt;
  694.     Pixel pixel;
  695.     int depth;
  696.  
  697.     data = (unsigned char *) image->data;
  698.     iptr = pmap->pixelindex;
  699.     depth = image->depth;
  700.     lbt = low_bits_table[depth];
  701.     for (y = 0; y < height; y++)
  702.     for (x = 0; x < width; x++, iptr++) {
  703.         pixel = data[ZINDEX8(x, y, image)];
  704.         if (depth != 8)
  705.         pixel &= lbt;
  706.         if (storePixel(pixel, pmap, iptr))
  707.         return (XpmNoMemory);
  708.     }
  709.     return (XpmSuccess);
  710. }
  711.  
  712. /*
  713.  * scan pixels of a 1-bit depth Z image data structure
  714.  */
  715.  
  716. static int
  717. GetImagePixels1(image, width, height, pmap, storeFunc)
  718.     XImage *image;
  719.     unsigned int width;
  720.     unsigned int height;
  721.     PixelsMap *pmap;
  722.     int (*storeFunc) ();
  723.  
  724. {
  725.     unsigned int *iptr;
  726.     int x, y;
  727.     char *data;
  728.     Pixel pixel;
  729.  
  730.     if (image->byte_order != image->bitmap_bit_order)
  731.     return (GetImagePixels(image, width, height, pmap));
  732.     else {
  733.     data = image->data;
  734.     iptr = pmap->pixelindex;
  735.     if (image->bitmap_bit_order == MSBFirst)
  736.         for (y = 0; y < height; y++)
  737.         for (x = 0; x < width; x++, iptr++) {
  738.             pixel = (data[ZINDEX1(x, y, image)] & (0x80 >> (x & 7)))
  739.             ? 1 : 0;
  740.             if ((*storeFunc) (pixel, pmap, iptr))
  741.             return (XpmNoMemory);
  742.         }
  743.     else
  744.         for (y = 0; y < height; y++)
  745.         for (x = 0; x < width; x++, iptr++) {
  746.             pixel = (data[ZINDEX1(x, y, image)] & (1 << (x & 7)))
  747.             ? 1 : 0;
  748.             if ((*storeFunc) (pixel, pmap, iptr))
  749.             return (XpmNoMemory);
  750.         }
  751.     }
  752.     return (XpmSuccess);
  753. }
  754.  
  755. int
  756. XpmCreateXpmImageFromPixmap(display, pixmap, shapemask,
  757.                 xpmimage, attributes)
  758.     Display *display;
  759.     Pixmap pixmap;
  760.     Pixmap shapemask;
  761.     XpmImage *xpmimage;
  762.     XpmAttributes *attributes;
  763. {
  764.     XImage *ximage = NULL;
  765.     XImage *shapeimage = NULL;
  766.     unsigned int width = 0;
  767.     unsigned int height = 0;
  768.     int ErrorStatus;
  769.  
  770.     /* get geometry */
  771.     if (attributes && attributes->valuemask & XpmSize) {
  772.     width = attributes->width;
  773.     height = attributes->height;
  774.     }
  775.  
  776.     /* get the ximages */
  777.     if (pixmap)
  778.     xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height);
  779.     if (shapemask)
  780.     xpmCreateImageFromPixmap(display, shapemask, &shapeimage,
  781.                  &width, &height);
  782.  
  783.     /* create the related XpmImage */
  784.     ErrorStatus = XpmCreateXpmImageFromImage(display, ximage, shapeimage,
  785.                          xpmimage, attributes);
  786.  
  787.     /* destroy the ximages */
  788.     if (ximage)
  789.     XDestroyImage(ximage);
  790.     if (shapeimage)
  791.     XDestroyImage(shapeimage);
  792.  
  793.     return (ErrorStatus);
  794. }
  795.